package com.github.live.util;

import android.os.Handler;
import android.util.ArrayMap;
import android.util.Log;

import com.github.livebase.util.base.CollectionsUtil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @ClassName HandlerWrapper
 * @description: handler的扩展类， 添加contains操作
 * @author: biao532
 * @create: 2023-12-31 14:53
 * @Version 1.0
 **/
public class HandlerWrapper {
    /**
     * 非线程安全的
     */
    private class InnerRunnable implements Runnable {
        private Runnable runnable;
        private HandlerWrapper manager;
        public InnerRunnable(Runnable runnable, HandlerWrapper manager) {
            this.runnable = runnable;
            this.manager = manager;
            manager.onNew(this);
        }
        @Override
        public void run() {
            if (!Thread.interrupted()) {
                manager.onRunning(this);
                runnable.run();
            }
            manager.onRunningDown(this);
        }
    }
    private Map<Runnable, List<InnerRunnable>> map;
    private Handler handler;
    public HandlerWrapper(Handler handler) {
        this.handler = handler;
        this.map = new ArrayMap<>();
    }

    public void postDelayed(Runnable runnable, long delay) {
        if (contains(runnable)) {
            removeCallbacks(runnable);
        }
        handler.postDelayed(new InnerRunnable(runnable, this), delay);
    }

    public void post(Runnable runnable) {
        postDelayed(runnable, 0);
    }
    public boolean contains(Runnable runnable) {
        List<InnerRunnable> list = map.get(runnable);
        return !CollectionsUtil.isEmpty(list);
    }

    public void removeCallbacks(Runnable runnable) {
        List<InnerRunnable> innerRunnable = map.get(runnable);
        if (innerRunnable == null) {
            return;
        }
        Collection<InnerRunnable> back = CollectionsUtil.copy(innerRunnable);
        CollectionsUtil.foreach(back, (r) -> {
            handler.removeCallbacks(r);
        });
        innerRunnable.removeAll(back);
        if (innerRunnable.isEmpty()) {
            map.remove(runnable);
        }
        LogFactory.debug("HandlerWrapper", "on remove size = {}}", map.size());
    }
    private void onNew(InnerRunnable running) {
        List<InnerRunnable> list = map.get(running.runnable);
        if (list == null) {
            list = new ArrayList<>();
            map.put(running.runnable, list);
        }
        list.add(running);
        LogFactory.debug("HandlerWrapper","on new size = {}", map.size());
    }
    private void onRunning(InnerRunnable running) {

    }
    private void onRunningDown(InnerRunnable runnable) {
        List<InnerRunnable> list = map.get(runnable.runnable);
        if (list != null) {
            list.remove(runnable);
        }
        LogFactory.debug("HandlerWrapper", "size = {}}", map.size());
    }
}
